/**
 * 菜单项接口定义
 */
import type {Menu} from "@/types/base.ts";

/**
 * 过滤策略接口
 */
interface FilterStrategy {
    filter(menus: Menu[], allowedIds: string[]): Menu[];
}

/**
 * 菜单过滤工具类
 * 支持多种过滤策略
 */
class MenuFilter {
    /**
     * 根据策略名称获取过滤器实例
     * @param strategy - 策略名称：'recursive' | 'twoLevel'
     * @returns 过滤器实例
     */
    static use(strategy: 'recursive' | 'twoLevel' = 'recursive'): FilterStrategy {
        const strategies = {
            recursive: new RecursiveFilter(),
            twoLevel: new TwoLevelFilter()
        };

        const filter = strategies[strategy];
        if (!filter) {
            console.warn(`[MenuFilter] 未知策略: ${strategy}，使用默认 recursive`);
            return strategies.recursive;
        }
        return filter;
    }
}

// ========================================
// 策略1：递归方式（适合任意层级）
// ========================================
class RecursiveFilter implements FilterStrategy {
    filter(menus: Menu[], allowedIds: string[]): Menu[] {
        const allowedSet = new Set(allowedIds);

        const isVisible = (menu: Menu): boolean => {
            // 如果自己有权限，可见
            if (allowedSet.has(String(menu.id))) {
                return true;
            }
            // 如果子菜单有可见的，也可见（作为目录）
            if (menu.children && menu.children.length > 0) {
                return menu.children.some(isVisible);
            }
            return false;
        };

        const buildTree = (menu: Menu): Menu | null => {
            if (!isVisible(menu)) return null;

            const result: Menu = { ...menu };

            if (menu.children && menu.children.length > 0) {
                result.children = menu.children
                    .map(buildTree)
                    .filter((item): item is Menu => item !== null);
            } else {
                result.children = [];
            }

            // 如果自己没权限但子菜单有权限，置灰
            if (!allowedSet.has(String(menu.id)) && result.children.length > 0) {
                result.visible = true;
            }

            return result;
        };

        return menus.map(buildTree).filter((item): item is Menu => item !== null);
    }
}

// ========================================
// 策略2：两层菜单循环方式
// ========================================
class TwoLevelFilter implements FilterStrategy {
    filter(allMenus: Menu[], allowedIds: string[]): Menu[] {
        const result: Menu[] = [];
        const allowedSet = new Set(allowedIds);

        for (const dir of allMenus) {
            // 显式获取 dir.id，确保其存在（如果可能缺失，可加断言或默认值）
            const { id, ...restDir } = dir;
            if (!id) {
                console.warn('菜单缺少 id 属性，已跳过', dir);
                continue; // 跳过无 id 的菜单，避免类型错误
            }

            // 创建 dirCopy 时，明确包含 id（确保必填项存在）
            const dirCopy: Menu = {
                id: id, // 显式赋值 id，消除可选性
                ...restDir,
                children: [],
                visible: true
            };

            let hasVisibleChild = false;

            if (dir.children && Array.isArray(dir.children)) {
                for (const menu of dir.children) {
                    if (allowedSet.has(String(menu.id))) { // 此时 menu.id 必存在（因 Menu 约束）
                        dirCopy.children!.push(menu);
                        hasVisibleChild = true;
                    }
                }
            }

            if (hasVisibleChild) {
                if (allowedSet.has(String(dir.id))) {
                    dirCopy.visible = false;
                }
                result.push(dirCopy);
            }
        }

        return result;
    }
}

// 命名导出 使用时：import { MenuFilter } from '@/utils/menuFilter';
export { MenuFilter, type Menu, type FilterStrategy };

// 默认导出 使用时：import MenuFilter from '@/utils/menuFilter';
// export default MenuFilter;